import pandas as pd
import numpy as np
import plotly.express as px
from datetime import datetime


def load_data(file_path):
    """加载CSV数据文件"""
    try:
        df = pd.read_csv(file_path)
        print("数据加载成功！基本信息：")
        print(df.info())
        print("\n数据前5行：")
        print(df.head())
        print("\n数据统计摘要：")
        print(df.describe())
        return df
    except Exception as e:
        print(f"数据加载失败：{e}")
        return None


def preprocess_data(df):
    """
    数据预处理函数
    :param df: 原始数据DataFrame
    :return: 处理后的DataFrame
    """
    if df is None:
        return None

    # 1. 处理缺失值
    print("\n各列缺失值比例：")
    missing_ratio = df.isnull().sum() / len(df)
    print(missing_ratio[missing_ratio > 0])

    # 数值型列用均值填充
    numeric_cols = df.select_dtypes(include='number').columns
    for col in numeric_cols:
        df[col] = df[col].fillna(df[col].mean())

    # 分类列用众数填充
    categorical_cols = df.select_dtypes(include='object').columns
    for col in categorical_cols:
        df[col] = df[col].fillna(df[col].mode()[0])

    # 2. 异常值处理
    for col in numeric_cols:
        Q1 = df[col].quantile(0.25)
        Q3 = df[col].quantile(0.75)
        IQR = Q3 - Q1
        lower_bound = Q1 - 1.5 * IQR
        upper_bound = Q3 + 1.5 * IQR
        df = df[(df[col] >= lower_bound) & (df[col] <= upper_bound)]

    # 3. 数据类型转换
    if 'Sex' in df.columns:
        df['Sex'] = df['Sex'].map({'male': 0, 'female': 1}).fillna(-1).astype(int)

    # 4. 特征工程
    if 'Age' in df.columns:
        df['AgeGroup'] = pd.cut(df['Age'], bins=[0, 18, 30, 50, 100],
                                labels=['Child', 'Young', 'Middle', 'Old'])

    return df


def save_results(df, base_path):
    """保存处理结果和报告"""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")

    # 保存处理后的数据
    output_path = f'{base_path}processed_data_{timestamp}.csv'
    df.to_csv(output_path, index=False)
    print(f"\n预处理后的数据已保存至：{output_path}")

    # 保存报告
    report_path = f'{base_path}data_preprocessing_report_{timestamp}.txt'
    with open(report_path, 'w', encoding='utf-8') as f:
        f.write("数据预处理报告\n")
        f.write(f"处理时间: {timestamp}\n")
        f.write(f"原始数据行数: {len(df)}\n")
        f.write(f"处理后数据行数: {len(df)}\n")
        f.write("\n处理步骤:\n")
        f.write("1. 缺失值处理\n2. 异常值处理\n3. 数据类型转换\n4. 特征工程")
    print(f"预处理报告已保存至：{report_path}")


def visualize_data(df):
    """数据可视化"""
    if 'Age' in df.columns and 'Sex' in df.columns:
        fig = px.histogram(df, x='Age', color='Sex',
                           title='年龄分布',
                           labels={'Sex': '性别', 'Age': '年龄'})
        fig.show()


if __name__ == "__main__":
    # 文件路径配置
    input_path = r'C:\Users\Lenovoo\Desktop\邵一川\课设\train_and_test2.csv'
    output_base = r'C:\Users\Lenovoo\Desktop\邵一川\课设\\'

    # 执行流程
    raw_data = load_data(input_path)
    processed_data = preprocess_data(raw_data)

    if processed_data is not None:
        save_results(processed_data, output_base)
        visualize_data(processed_data)
